package gui.product;

import core.ItemFacade;
import core.Product;
import gui.common.Tagable;

/**
 * Display data class for products.
 */
public class ProductData extends Tagable implements Comparable<ProductData>
{
	private String _description;	//description of the attribute
	private String _sizeUnit;		//size attribute
	private String _sizeValue;		
	private String _count;			//count attribute
	private String _shelfLife;		//shelf life attribute
	private String _supply;			//supply attribute
	private String _barcode;		//barcode attribute
	private static ItemFacade _iFacade = ItemFacade.instance();
	
	/**		
	 * Constructor.		
	 *		
	 * {@pre None}		
	 *		
	 * {@post getDescription() == ""}		
	 * {@post getSize() == "count"}		
	 * {@post getCount() == "1"}		
	 * {@post getShelfLife() == "0"}		
	 * {@post getSupply() == "0"}		
	 * {@post getBarcode() == barcode}		
	 */		
	public ProductData(String barcode) {		
		_description = "";		
		_sizeUnit = "count";		
		_sizeValue = "1";		
		_count = "0";		
		_shelfLife = "0";		
		_supply = "0";		
		_barcode = barcode;		
	}		

	public ProductData()		
	{		
		this("");		
	}
	
	/**
	 * Constructor
	 * Convert a product to a ProductData
	 * 
	 * @param object the product object to convert from
	 * 
	 * @throws IllegalArgumentException thrown if object is null or cannot be converted to Product
	 */
	public ProductData(Object object) throws IllegalArgumentException
	{
		if (object == null || !(object instanceof Product))
			throw new IllegalArgumentException ("Object cannot be null");
		
		this.setTag(object);
		reloadProductData();
	}

	public void reloadProductData() {
		try
		{
			Product product = getProduct();
			_description = product.getDescription();
			_sizeUnit = product.getUnitOfMeasurement();
			//be careful about the size value
			float val = product.getQuantityForOneUnit();
			if (val - (int)val == 0) {
				_sizeValue = Integer.toString((int)val);
			}
			else {
				_sizeValue = Float.toString(product.getQuantityForOneUnit());
			}
			_shelfLife = Integer.toString(product.getShelfLife());
			_supply = Integer.toString(product.getThreeMonthSupply());
			_barcode = product.getBarcode().toString();
			updateCount();
		}
		catch (Exception e)
		{
			e.printStackTrace();
			throw new IllegalArgumentException("Object cannot be converted to a product");
		}
	}
	
	
	public void updateCount()
	{
		_count = Integer.toString(_iFacade.getNumberOfItemsInProduct(_barcode));
	}
	
	/**
	 * Returns the value of the Barcode attribute.
	 */
	public String getBarcode() {
		return _barcode;
	}

	/**
	 * Sets the value of the Barcode attribute.
	 * 
	 * @param barcode New Barcode value
	 * 
	 * {@pre barcode != null}
	 * 
	 * {@post getBarcode() == barcode}
	 */
	public void setBarcode(String barcode) throws IllegalArgumentException
	{
		if (barcode == null)
			throw new IllegalArgumentException("ProductData barcode cannot be null");
		this._barcode = barcode;
	}

	/**
	 * Returns the value of the Description value.
	 */
	public String getDescription() {
		return _description;
	}

	/**
	 * Sets the value of the Description value.
	 * 
	 * @param description New Description value
	 * 
	 * {@pre description != null}
	 * 
	 * {@post getDescription() == description}
	 */
	public void setDescription(String description) throws IllegalArgumentException
	{
		if (description == null)
			throw new IllegalArgumentException("ProductData description cannot be null");
		this._description = description;
	}

	/**
	 * Returns the size attribute
	 */
	public String getSizeString()
	{
		return _sizeValue + " " + _sizeUnit;
	}
	
	/**
	 * Returns the unit of the Size
	 */
	public String getSizeUnit() {
		return _sizeUnit;
	}
	
	/**
	 * Returns the value of the Size
	 * @return
	 */
	public String getSizeValue()
	{
		return _sizeValue;
	}

	/**
	 * Sets the unit of the Size attribute.
	 * 
	 * @param sizeUnit New Size value
	 * 
	 * {@pre size != null}
	 * 
	 * {@post getSize() == size}
	 */
	public void setSizeUnit(String sizeUnit) throws IllegalArgumentException 
	{
		if (sizeUnit == null)
			throw new IllegalArgumentException("ProductData size cannot be null");
		this._sizeUnit = sizeUnit;
	}
	
	/**
	 * Sets the value of the Size attribute.
	 * 
	 * @param sizeValue New Size value
	 * 
	 * {@pre size != null}
	 * 
	 * {@post getSize() == size}
	 */
	public void setSizeValue(String sizeValue) throws IllegalArgumentException 
	{
		if (sizeValue == null)
			throw new IllegalArgumentException("ProductData size cannot be null");
		this._sizeValue = sizeValue;
	}

	/**
	 * Returns the value of the Count attribute.
	 */
	public String getCount() {
		return _count;
	}
	
	/**
	 * Sets the value of the Count attribute.
	 * 
	 * @param count New Count value
	 * 
	 * {@pre count >= 0}
	 * {@post getCount() == count}
	 */
	public void setCount(int count) throws IllegalArgumentException 
	{
		if (count < 0)
			throw new IllegalArgumentException("ProductData count cannot be negative");
		this._count = Integer.toString(count);
	}

    /**
     * Sets the value of the Count attribute.
     * 
     * @param count New Count value
     * 
     * {@pre count != null}
     * {@pre count >= 0}
     * {@post getCount() == count}
     */
    public void setCount(String count) throws IllegalArgumentException 
    {
            if (count == null)
                    throw new IllegalArgumentException("ProductData count cannot be null");
            if (Integer.parseInt(count) < 0)
                    throw new IllegalArgumentException("ProductData count cannot be negative");
            this._count = count;
    }

	/**
	 * Returns the value of the Shelf Life attribute.
	 */
	public String getShelfLifeSting() 
	{
		return _shelfLife + " months";
	}
	
	public String getShelfLife()
	{
		return _shelfLife;
	}

	/**
	 * Sets the value of the Shelf Life attribute.
	 * 
	 * @param shelfLife New Shelf Life value
	 * 
	 * {@pre shelfLife != null}
	 * 
	 * {@post getShelfLife() == shelfLife}
	 */
	public void setShelfLife(String shelfLife) throws IllegalArgumentException
	{
		if (shelfLife == null)
			throw new IllegalArgumentException("ProductData shelf life cannot be null");
		this._shelfLife = shelfLife;
	}

	/**
	 * Returns the value of the Supply attribute.
	 */
	public String getSupplyString() {
		return _supply + " count";
	}

	public String getSupply()
	{
		return _supply;
	}
	/**
	 * Sets the value of the Supply attribute.
	 * 
	 * @param supply New Supply value
	 * 
	 * {@pre supply != null}
	 * 
	 * {@post getSupply() == supply}
	 */
	public void setSupply(String supply) throws IllegalArgumentException
	{
		if (supply == null)
			throw new IllegalArgumentException("ProductData supply cannot be null");
		this._supply = supply;
	}
	
	/**
	 * Returns the product associated with the ProductData
	 * 
	 * @return the ProductData's product, returns null if no product
	 */
	public Product getProduct(){
		Product product = (Product)this.getTag();
		return product;
	}

	@Override
	public int compareTo(ProductData o) {
		return _description.compareTo(o._description);
	}


}

